#include "properties.h"

property_t *property_create(char *name, char *description, property_value_type_t type, property_value_t value)
{
    property_t *property = (property_t *)object_new(sizeof(property_t));
    assert(property);
    property->name = strdup(name);
    property->description = strdup(description);
    property->type = type;
    if (type == PROPERTY_VALUE_TYPE_STRING)
    {
        property->value.str = strdup(value.str);
    }
    else
    {
        property->value = value;
    }

    return property;
}

property_t *property_list_get(property_list_t *list, char *name)
{
    foreach_in_list(property_t *, property, list)
    {
        if (strcmp(property->name, name) == 0)
        {
            return property;
        }
    }
    return NULL;
}

cJSON *property_list_get_descriptor_json(property_list_t *list)
{
    cJSON *root = cJSON_CreateObject();
    assert(root);
    foreach_in_list(property_t *, property, list)
    {
        cJSON *prop = cJSON_CreateObject();
        assert(prop);
        cJSON_AddStringToObject(prop, "description", property->description);
        switch (property->type)
        {
        case PROPERTY_VALUE_TYPE_BOOL:
            cJSON_AddStringToObject(prop, "type", "bool");
            break;
        case PROPERTY_VALUE_TYPE_NUMBER:
            cJSON_AddStringToObject(prop, "type", "number");
            break;
        case PROPERTY_VALUE_TYPE_STRING:
            cJSON_AddStringToObject(prop, "type", "string");
            break;
        default:
            break;
        }
        cJSON_AddItemToObject(root, property->name, prop);
    }
    return root;
}

cJSON *property_list_get_state_json(property_list_t *list)
{
    cJSON *root = cJSON_CreateObject();
    assert(root);
    foreach_in_list(property_t *, property, list)
    {
        switch (property->type)
        {
        case PROPERTY_VALUE_TYPE_BOOL:
            cJSON_AddBoolToObject(root, property->name, property->value.boolean);
            break;
        case PROPERTY_VALUE_TYPE_NUMBER:
            cJSON_AddNumberToObject(root, property->name, property->value.number);
            break;
        case PROPERTY_VALUE_TYPE_STRING:
            cJSON_AddStringToObject(root, property->name, strdup(property->value.str));
        }
    }
    return root;
}
